<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>example</title>
	</head>
	<body>
		<script>
			{
				function VueCom(data) {
					this.data = data;
				}
				const com1 = new VueCom({ name: 'one' });
				console.log(com1.data);

				const com2 = new VueCom({ name: 'two' });
				console.log(com2.data);

				com1.data.name = 'three';
				console.log(com1.data);
				console.log(com2.data);
			}

			{
				let s1 = new String('some text');
				s1.color = 'red';
				console.log(s1);

				console.log(s1.color);
			}
			{
				let vectorLis = new Array(10);
				console.log(vectorLis);
				vectorLis.push({});
				console.log(vectorLis);
			}
			{
				let arr = [1, 2, 3];
				console.log('🌈 —— data-arr --->', arr);
				delete arr[0];
				console.log('🌈 —— data-arr --->', arr);
				arr = arr.filter((v) => Boolean(v));
				console.log('🌈 —— data-arr --->', arr);

				const obj = {
					name: 'jack',
					age: 19
				};

				delete obj.age;
				console.log('🌈 —— data-obj --->', obj);
			}

			// 创建对象
			let o = new Object();
			// ecma只要求在给构造函数提供参数时使用括号
			// 1. 无参数时，可以省略括号
			let o1 = new Object(); // 合法，但不推荐

			// 每个 Object 实例都有如下属性和方法
			// 1. constructor：用于创建当前对象的构造函数
			// 2. hasOwnProperty(propertyName)：用于检查当前对象实例（不是原型）是否包含指定的属性
			// 3. isPrototypeOf(object)：用于检查当前对象是否是传入对象的原型
			// 4. propertyIsEnumerable(propertyName)：用于检查指定的属性是否可以使用 for-in 语句枚举
			// 5. toLocaleString()：返回对象的本地化字符串表示
			// 6. toString()：返回对象的字符串表示
			// 7. valueOf()：返回对象的字符串、数值或布尔值表示
			// 8. __proto__：指向当前对象的原型对象
			// 9. prototype：指向当前对象的原型对象
			// 10. __defineGetter__()：定义对象的属性的 getter
			// 11. __defineSetter__()：定义对象的属性的 setter
			// 12. __lookupGetter__()：返回对象的属性的 getter
			// 13. __lookupSetter__()：返回对象的属性的 setter
			// 14. get __proto__()：返回对象的原型对象
			// 15. set __proto__()：设置对象的原型对象
			// 16. get constructor()：返回对象的构造函数
			// 17. set constructor()：设置对象的构造函数
			// 20. get prototype()：返回对象的原型对象
			// 21. set prototype()：设置对象的原型对象

			// 操作符
			// 操作符在应用给对象时，会调用对象的 valueOf() 方法，然后再调用 toString() 方法
			{
				// 1元操作符(unary operator)
				// 1. 递增和递减操作符
				let age = 29;
				++age; // 30
				/**
				 * let age = 29
				 * age = age + 1
				 */
				// 变量的值会在表达式被求值之前被递增
			}

			{
				// const n1 = 30
				// const n2 = 10
				// const result = ++n1 + n2++
			}

			{
				let w = 1 && 0; // 0
				let n = 0 && 1; // 0
				let c = 1 && 1; // 1
				let d = 0 && 0; // 0
				// console.log(w, n, c, d) // 0 0 1 0

				const a = false && { a: 'your' };
				// console.log(a)
			}
			{
				let w = 'a' && 'b';
				let n = {} && false;
				let c = 0 && 'c';
				let d = [] && {};
				// console.log(w, n, c, d) // b false 0 {}
			}
			console.log('-------------------');
			{
				const a = false || 0;
				// console.log(a)
			}

			{
				let a = 1,
					b = 2,
					c = 3;
			}

			{
				for (const propName in window) {
					document.write(`${propName}<br>`);
				}
			}

			{
				// hasOwnProperty
				const obj = {};
				console.log(obj.hasOwnProperty('name')); // false
				obj.name = 'flame';
				console.log(obj.hasOwnProperty('name')); // true;
			}

			{
				const arr = [1, 2, 3];
				for (const i in arr) {
					console.log(arr[i]);
				}
				for (const i of arr) {
					console.log(i);
				}
			}

			{
				console.log(window.indexedDB);
			}
		</script>
	</body>
</html>
